/* 
 * File:   Perimetro.cpp
 * Author: 75.02 - Grupo 7, 2do cuatrimestre 2012.
 * 
 * Created on November 3, 2012, 7:44 PM
 */

#include <sstream>
#include "Perimetro.h"

using namespace TP::Juego::Arena::Utilidades;

Perimetro::Perimetro() {
	_rol = new Rol(ROL_PERIMETRO, DESC_PERIMETRO);
	_vida = VIDA_PERIMETRO;
	_puntaje = PUNTAJE_PERIMETRO;
	this->_alto = 0;
	this->_ancho = 0;
}

Perimetro::Perimetro(unsigned long int pAlto, unsigned long int pAncho) {
	_rol = new Rol(ROL_PERIMETRO, DESC_PERIMETRO);
	_vida = VIDA_PERIMETRO;
	_puntaje = PUNTAJE_PERIMETRO;
	this->_alto = pAlto;
	this->_ancho = pAncho;
}

Perimetro::~Perimetro() { }

unsigned long int Perimetro::getAlto() {
	return this->_alto;
}

unsigned long int Perimetro::getAncho() {
	return this->_ancho;
}

bool Perimetro::pertenecePerimetro(Posicion* pPosicion) {

	bool pertenece = false;

	if (pPosicion) {
		pertenece = true;
		pertenece = pertenece && pPosicion->X() > 0;
		pertenece = pertenece && pPosicion->X() < this->getAncho() - 1;
		pertenece = pertenece && pPosicion->Y() > 0;
		pertenece = pertenece && pPosicion->Y() < this->getAlto() - 1;
	}

	return pertenece;
}

Vector2D* Perimetro::getNormalAPuntoPerimetro(Posicion* pPosicion) {

	// Por default, la posicion no corresponde a un punto del perimetro.
	// Por ende, no tiene una normal definida.

	Vector2D* normal = new Vector2D(0, 0);

	if (pPosicion->X() == 0) {
		normal->X(1);

		if (pPosicion->Y() == 0)
			normal->Y(1);

		else if (pPosicion->Y() == this->getAlto() - 1)
			normal->Y(-1);

		else
			normal->Y(0);
	}
	else if (pPosicion->X() == this->getAncho() - 1) {
		normal->X(-1);

		if (pPosicion->Y() == 0)
			normal->Y(1);

		else if (pPosicion->Y() == this->getAlto() - 1)
			normal->Y(-1);

		else
			normal->Y(0);
	}
	else if (pPosicion->Y() == 0) {
		normal->Y(1);

		if (pPosicion->X() == 0)
			normal->X(1);
		else if (pPosicion->X() == this->getAncho() - 1)
			normal->X(-1);
		else
			normal->X(0);
	}
	else if (pPosicion->Y() == this->getAlto() - 1) {
		normal->Y(-1);

		if (pPosicion->X() == 0)
			normal->X(1);
		else if (pPosicion->X() == this->getAncho() - 1)
			normal->X(-1);
		else
			normal->X(0);
	}

	return normal;
}

Vector2D* Perimetro::getPuntoAdjuntoInterior(Posicion* pPosicion) {

	Vector2D* interior = new Vector2D(0, 0);

	if (pPosicion->X() == 0) {
		interior->X(1);

		if (pPosicion->Y() == 0)
			interior->Y(1);

		else if (pPosicion->Y() == this->getAlto() - 1)
			interior->Y(-1);

		else
			interior->Y(pPosicion->Y());
	}
	else if (pPosicion->X() == this->getAncho() - 1) {
		interior->X(-1);

		if (pPosicion->Y() == 0)
			interior->Y(1);

		else if (pPosicion->Y() == this->getAlto() - 1)
			interior->Y(-1);

		else
			interior->Y(pPosicion->Y());
	}
	else if (pPosicion->Y() == 0) {
		interior->Y(1);

		if (pPosicion->X() == 0)
			interior->X(1);
		else if (pPosicion->X() == this->getAncho() - 1)
			interior->X(-1);
		else
			interior->X(pPosicion->X());
	}
	else if (pPosicion->Y() == this->getAlto() - 1) {
		interior->Y(-1);

		if (pPosicion->X() == 0)
			interior->X(1);
		else if (pPosicion->X() == this->getAncho() - 1)
			interior->X(-1);
		else
			interior->X(pPosicion->X());
	}

	return interior;
}

TiXmlElement* Perimetro::aElementoXML() {

	TiXmlElement * element = new TiXmlElement(_rol->Nombre().c_str());

	element->SetDoubleAttribute("vida", _vida);
	element->SetDoubleAttribute("puntaje", _puntaje);

	std::stringstream stream;
	stream << this->_alto;
	element->SetAttribute("alto", stream.str().c_str());

	stream.str(std::string());
	stream << this->_ancho;
	element->SetAttribute("ancho", stream.str().c_str());

	return element;
}

void Perimetro::deElementoXML(TiXmlElement* pElemento) {

	if (strcmp(pElemento->Value(), _rol->Nombre().c_str()) == 0) {
		pElemento->Attribute("vida", &_vida);
		pElemento->Attribute("puntaje", &_puntaje);
		std::stringstream(pElemento->Attribute("alto")) >> this->_alto;
		std::stringstream(pElemento->Attribute("ancho")) >> this->_ancho;
	}
}

double Perimetro::getRadio() {
    return radio_perimetro;
}

int Perimetro::getPuntos() const {
    return PUNTAJE_PERIMETRO;
}